#ifndef CORE_FILE_H
#define CORE_FILE_H
#include <core/core.h>
#include <core/string.h>

namespace Core
{
    typedef boost::error_info<struct msg_filename, Core::String> ExceptionFileName;
    
    class CORE_API IODevice
    {
    public:
        enum OpenMode
        {
            Invalid    = 0x0,
            WriteOnly  = 0x1,
            ReadOnly   = 0x2,
            ReadWrite  = WriteOnly | ReadOnly,
            Append     = 0x4,
            Truncate   = 0x8,
        };

        virtual void flush() = 0;
        virtual bool write(const Byte* data, ULong szInBytes) = 0;
        virtual bool read(Byte* inData, ULong szInBytes) = 0;
        virtual bool isWriteable() const = 0;
        virtual bool isReadable()  const = 0;
        virtual bool isValid() const = 0;
    };

    class CORE_API File : public IODevice
    {
    public:
        File();
        ~File();

        void close();
        bool open(OpenMode mode, const String& fileName);
        void flush();
        bool write(const Byte* data, ULong szInBytes);
        bool read(Byte* inData, ULong szInBytes);
        bool isWriteable() const;
        bool isReadable()  const;
        bool isValid() const;

    private:
        HANDLE   m_file;
        String   m_fileName;
        OpenMode m_openMode;
        
        //denied
        File(const File& file);
        const File& operator=(const File& f);
    };
}

#endif